package com.emperor.treatment.app;

import java.util.ArrayList;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;

import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;

import com.emperor.cashier.app.CashierAppCtrl;
import com.emperor.category.logic.Category;
import com.emperor.category.logic.CategoryModel;
import com.emperor.core.app.App;
import com.emperor.core.app.AppBase;
import com.emperor.core.app.AppConstant;
import com.emperor.employee.logic.Employee;
import com.emperor.transaction.logic.Transaction;
import com.emperor.treatment.logic.Treatment;
import com.emperor.treatment.logic.TreatmentModel;
import com.emperor.user.logic.User;
import com.emperor.util.HibernateUtil;
import com.swtdesigner.SWTResourceManager;

public class TreatmentAppNew extends AppBase implements App {

	private Label categoryLabel_1_3;
	private Text text_10;
	private Text text_7;
	private Combo combo;
	private Text text_6;
	private Text text_5;
	private Text text_4;
	private Text text_3;
	private Text text_2;
	private Text text;
	protected Shell shlNewTreatment;

	public static Logger log = Logger.getLogger(TreatmentAppNew.class);

	public TreatmentAppNew() {
		super();
	}

	public TreatmentAppNew(Map<String, Object> params) {
		super();
		this.params = params;
	}

	/**
	 * Launch the application
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			TreatmentAppNew window = new TreatmentAppNew();
			window.open();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * Open the window
	 */
	public void open() {
		final Display display = Display.getDefault();
		createContents();
		shlNewTreatment.open();
		shlNewTreatment.layout();
		while (!shlNewTreatment.isDisposed()) {
			if (!display.readAndDispatch())
				display.sleep();
		}
	}

	/**
	 * Create contents of the window
	 */
	protected void createContents() {
		shlNewTreatment = new Shell();
		shlNewTreatment.setBackgroundImage(SWTResourceManager.getImage(
				TreatmentAppNew.class, "/img/main.jpg"));
		shlNewTreatment.setImage(SWTResourceManager.getImage(
				TreatmentAppNew.class, "/img/iMac OSX.png"));
		shlNewTreatment.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		shlNewTreatment.setBackgroundMode(SWT.INHERIT_DEFAULT);
		shlNewTreatment.setSize(1280, 800);
		shlNewTreatment.setText("New Treatment");

		initScreen(shlNewTreatment, getParams());

		final Composite composite = new Composite(shlNewTreatment, SWT.NONE);
		composite.setBounds(0, 50, 992, 527);

		final Label messageLabel = new Label(composite, SWT.NONE);
		messageLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		messageLabel
				.setText("Please key in the New Treatment Form below and click Save to add New Treatment");
		messageLabel.setBounds(10, 10, 673, 20);

		final Label label = new Label(composite, SWT.NONE);
		label.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI",
				12, SWT.NORMAL));
		label.setText("Category");
		label.setBounds(10, 70, 65, 20);

		final Label categoryLabel = new Label(composite, SWT.NONE);
		categoryLabel.setBounds(10, 108, 65, 20);
		categoryLabel.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel.setText("Name");

		final Label categoryLabel_1 = new Label(composite, SWT.NONE);
		categoryLabel_1.setBounds(10, 143, 65, 20);
		categoryLabel_1.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_1.setText("SKU");

		final Label categoryLabel_2 = new Label(composite, SWT.NONE);
		categoryLabel_2.setBounds(10, 331, 80, 20);
		categoryLabel_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_2.setText("Description");

		final Label categoryLabel_3 = new Label(composite, SWT.NONE);
		categoryLabel_3.setBounds(10, 214, 35, 20);
		categoryLabel_3.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_3.setText("Price");

		final Label categoryLabel_4 = new Label(composite, SWT.NONE);
		categoryLabel_4.setBounds(10, 257, 65, 20);
		categoryLabel_4.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_4.setText("Discount");

		final Label categoryLabel_5 = new Label(composite, SWT.NONE);
		categoryLabel_5.setBounds(10, 293, 65, 20);
		categoryLabel_5.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		categoryLabel_5.setText("Quantity");

		text = new Text(composite, SWT.BORDER);
		text.setToolTipText("treatment_name");
		text.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI",
				12, SWT.NORMAL));
		text.setBounds(129, 105, 477, 30);

		text_2 = new Text(composite, SWT.BORDER);
		text_2.setToolTipText("treatment_sku");
		text_2.setBounds(129, 140, 477, 30);
		text_2.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_3 = new Text(composite, SWT.BORDER);
		text_3.setToolTipText("treatment_price");
		text_3.setBounds(129, 211, 172, 30);
		text_3.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_4 = new Text(composite, SWT.BORDER);
		text_4.setToolTipText("treatment_discount");
		text_4.setBounds(129, 247, 172, 30);
		text_4.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_5 = new Text(composite, SWT.BORDER);
		text_5.setToolTipText("treatment_quantity");
		text_5.setBounds(129, 290, 172, 30);
		text_5.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		text_6 = new Text(composite, SWT.WRAP | SWT.V_SCROLL | SWT.MULTI
				| SWT.BORDER);
		text_6.setToolTipText("treatment_desc");
		text_6.setBounds(129, 328, 477, 129);
		text_6.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		combo = new Combo(composite, SWT.NONE);
		combo.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont("Segoe UI",
				12, SWT.NORMAL));
		combo.setBounds(129, 67, 477, 28);

		text_7 = new Text(composite, SWT.BORDER);
		text_7.setVisible(false);
		text_7.setBounds(709, 355, 172, 30);
		text_7.setToolTipText("prod_weight");
		text_7.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));

		final Label categoryLabel_6 = new Label(composite, SWT.NONE);
		categoryLabel_6.setVisible(false);
		categoryLabel_6.setBounds(590, 358, 65, 20);
		categoryLabel_6.setFont(SWTResourceManager.getFont("", 12, SWT.NONE));
		categoryLabel_6.setText("Weight");

		buildStandardMenu(getShell(), getParams(),
				TreatmentAppCtrl.TREATMENT_CTRL, TreatmentAppCtrl.TREATMENT_ENQ);
		populateCombo(combo);

		text_10 = new Text(composite, SWT.BORDER);
		text_10.setBounds(129, 176, 172, 30);
		text_10.setToolTipText("treatment_cost");
		text_10.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));

		categoryLabel_1_3 = new Label(composite, SWT.NONE);
		categoryLabel_1_3.setBounds(10, 179, 65, 20);
		categoryLabel_1_3.setFont(org.eclipse.wb.swt.SWTResourceManager
				.getFont("Segoe UI", 12, SWT.NORMAL));
		categoryLabel_1_3.setText("Cost");

		final Button saveButton = new Button(composite, SWT.NONE);
		saveButton.setBounds(129, 463, 75, 30);
		saveButton.setImage(SWTResourceManager.getImage(TreatmentAppNew.class,
				"/img/Save.png"));
		saveButton.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				try {
					if (combo.getText() != null && combo.getText().length() > 0) {
						Treatment treatment = new TreatmentModel();

						Session session = HibernateUtil.getSessionFactory()
								.getCurrentSession();
						session.beginTransaction();

						Category category = new CategoryModel();
						List<Category> categories = session
								.createCriteria(CategoryModel.class)
								.add(Expression.eq(Category.FLD_NAME,
										combo.getText())).list();
						if (categories != null && !categories.isEmpty()) {
							category = categories.get(0);
						}

						treatment = (Treatment) setModel(composite,
								"treatment", treatment);
						treatment.setCategory(category);
						log.debug(treatment.getClass().getSimpleName() + " : "
								+ treatment.getValues().toString());

						List<String> errors = validateForm(treatment);
						if (errors.isEmpty()) {
							treatment = (Treatment) preAdd(treatment,
									getParams());

							treatment.setStatus(AppConstant.STATUS_ACTIVE);

							int rowCount = doAdd(treatment);

							if (rowCount == 1) {
								message(getShell(), "Save Success.",
										"Treatment added successfully.");

								getParams().put(AppConstant.APPCTRL,
										TreatmentAppCtrl.TREATMENT_CTRL);
								getParams().put(AppConstant.ACTION,
										TreatmentAppCtrl.TREATMENT_ENQ);
								getShell().close();
							} else {
								message(getShell(), "Save Error.",
										"Unable to add treatment.",
										SWT.ICON_ERROR | SWT.OK);
							}
						} else {
							message(getShell(), "Save Error", errors,
									SWT.ICON_ERROR | SWT.OK);
						}
					} else {
						message(getShell(), "Save Error.",
								"Please select a category.", SWT.ICON_ERROR
										| SWT.OK);
					}
				} catch (Exception ex) {
					message(getShell(), "Save Error.", ex.getMessage(),
							SWT.ICON_ERROR | SWT.OK);
					log.error(ex.getMessage(), ex);
				}
			}
		});
		saveButton.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		saveButton.setText("Save");

		final Button saveButton_1 = new Button(composite, SWT.NONE);
		saveButton_1.setBounds(210, 463, 80, 30);
		saveButton_1.addSelectionListener(new SelectionAdapter() {
			public void widgetSelected(final SelectionEvent e) {
				getShell().close();
			}
		});
		saveButton_1.setImage(SWTResourceManager.getImage(
				TreatmentAppNew.class, "/img/Refresh.png"));
		saveButton_1.setFont(org.eclipse.wb.swt.SWTResourceManager.getFont(
				"Segoe UI", 12, SWT.NORMAL));
		saveButton_1.setText("Reset");
		composite.setTabList(new Control[] { combo, text, text_2, text_10,
				text_3, text_4, text_5, text_6 });
	}

	public static List<String> validateForm(Treatment treatment)
			throws Exception {
		List<String> errors = new ArrayList<String>();

		if (StringUtils.isEmpty(treatment.getName())) {
			errors.add("Name cannot be empty.");
		}
		if (StringUtils.isEmpty(treatment.getSku())) {
			errors.add("SKU cannot be empty.");
		}
		if (treatment.getPrice() == null) {
			errors.add("Price cannot be empty.");
		}
		if (treatment.getCost() == null) {
			errors.add("Cost cannot be empty.");
		}
		if (treatment.getQuantity() == null) {
			errors.add("Quantity cannot be empty.");
		}

		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		session.beginTransaction();

		// List<Product> products = new ArrayList<Product>();
		// Criteria cris = session.createCriteria(ProductModel.class).add(
		// Expression.eq(Product.FLD_NAME,
		// product.getName())).add(Expression.eq(Product.FLD_STATUS,
		// AppConstant.STATUS_ACTIVE));
		// if (product.getId() != null) {
		// cris.add(Expression.ne(Product.FLD_ID, product.getId()));
		// }
		// products = cris.list();
		// if (products != null && !products.isEmpty()) {
		// errors.add("Duplicate product name. Please use another name.");
		// }

		List<Treatment> treatments = new ArrayList<Treatment>();
		Criteria cris = session
				.createCriteria(TreatmentModel.class)
				.add(Expression.eq(Treatment.FLD_SKU, treatment.getSku()))
				.add(Expression.eq(Treatment.FLD_STATUS,
						AppConstant.STATUS_ACTIVE));
		if (treatment.getId() != null) {
			cris.add(Expression.ne(Treatment.FLD_ID, treatment.getId()));
		}
		treatments = cris.list();
		if (treatments != null && !treatments.isEmpty()) {
			errors.add("Duplicate treatment SKU. Please use another SKU.");
		}

		if (treatment.getCategory() == null) {
			errors.add("Category cannot be empty.");
		}

		return errors;
	}

	private int doAdd(Treatment treatment) throws Exception {
		int rowCount = 0;
		Session session = HibernateUtil.getSessionFactory().getCurrentSession();
		try {
			session.beginTransaction();

			session.save(treatment);
			rowCount++;
			log.debug(treatment.getClass().getSimpleName() + " : "
					+ treatment.getValues().toString());

			session.getTransaction().commit();
		} catch (Exception e) {
			session.getTransaction().rollback();
			log.error(e.getMessage(), e);
			throw e;
		}
		return rowCount;
	}

	private void populateCombo(Combo combo) {
		try {
			Session session = HibernateUtil.getSessionFactory()
					.getCurrentSession();
			session.beginTransaction();
			List<Category> categories = session
					.createCriteria(CategoryModel.class)
					.add(Restrictions.eq(Category.FLD_TYPE,
							Category.TYPE_TREATMENT))
					.add(Restrictions.eq(Category.FLD_STATUS,
							AppConstant.STATUS_ACTIVE)).list();
			if (categories != null && !categories.isEmpty()) {
				for (Iterator<Category> iter = categories.iterator(); iter
						.hasNext();) {
					Category category = iter.next();
					combo.add(category.getName());
					combo.setData(category.getName(), category);
				}
			}
		} catch (Exception e) {
			log.error(e.getMessage(), e);
		}
	}

	public Shell getShell() {
		return shlNewTreatment;
	}

}
